package net.csdn.business.kanban.api.facade;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import net.csdn.business.kanban.api.entity.KanbanField;
import net.csdn.business.kanban.api.entity.KanbanView;
import net.csdn.business.kanban.api.enums.SystemFieldEnums;
import net.csdn.business.kanban.api.service.*;
import net.csdn.business.kanban.common.domain.request.KanbanUpdateViewParam;
import net.csdn.business.kanban.common.domain.request.KanbanViewAddParam;
import net.csdn.business.kanban.common.domain.request.KanbanViewMoveParam;
import net.csdn.business.kanban.common.domain.resp.KanbanViewResp;
import net.csdn.business.kanban.common.enums.ResultCodeEnum;
import net.csdn.business.kanban.common.exception.BusinessException;
import net.csdn.business.kanban.common.utils.ExceptionUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;

/**
 * @ClassName KanbanFacade
 * @Description TODO
 * @Author liuzhisheng
 * @Date 2023/9/18
 **/
@Service
@RequiredArgsConstructor
public class KanbanViewFacade {
    private final KanbanViewService kanbanViewService;
    private final KanbanFieldService kanbanFieldService;

    /**
     * 新建view
     * @param kanbanId
     * @param kanbanId 当前用户ID
     * @return
     */
    public boolean addOrCopeKanbanView(String kanbanId, KanbanViewAddParam kanbanViewAddParam){
        KanbanView kanbanView = new KanbanView();
            /**当viewId为空时表示新增*/
        if(kanbanViewAddParam.getViewId() == null){
            if(Objects.isNull(kanbanViewAddParam.getFieldDisplayJson()) || kanbanViewAddParam.getFieldDisplayJson().size() == 0){
                JSONArray array = new JSONArray();
                for (SystemFieldEnums systemFieldEnums : SystemFieldEnums.values()) {
                    /**系统定义字段*/
                    JSONObject viewObject1 = new JSONObject();
                    viewObject1.set(systemFieldEnums.getName(),true);
                    array.add(viewObject1);
                }
                List<KanbanField> kanbanField = kanbanFieldService.getFieldsByKbId(kanbanId);
                kanbanField.forEach(bean -> {
                    JSONObject viewObject2 = new JSONObject();
                    if(bean.getUserDefined()){
                        viewObject2.set(bean.getId().toString(),true);
                    }else {
                        viewObject2.set(bean.getId().toString(),false);
                    }
                    array.add(viewObject2);
                });
                kanbanView.setFieldDisplayJson(array.toString());
            }else {
                kanbanView.setFieldDisplayJson(kanbanViewAddParam.getFieldDisplayJson().toString());
            }
            if(Objects.nonNull(kanbanViewAddParam.getFilterObj())){
                kanbanView.setFilterObj(kanbanViewAddParam.getFilterObj().toString());
            }
        }else{
            KanbanView kanbanView1 = kanbanViewService.getKanbanView(kanbanId,kanbanViewAddParam.getViewId());
            if(kanbanView1 == null){
                throw new BusinessException(ResultCodeEnum.KANBAN_ADD_ERROR);
            }
            kanbanView.setFilterObj(kanbanView1.getFilterObj());
            kanbanView.setFieldDisplayJson(kanbanView1.getFieldDisplayJson());
        }
        kanbanView.setKanbanId(kanbanId);
        /**获取当前看板下view的最高优先级*/
        HashMap<String, Integer> map = kanbanViewService.getViewMap(kanbanId);
        kanbanView.setViewNumber(map.get("view_number") != null ? map.get("view_number")+1 : 1);
        kanbanView.setViewName("View "+kanbanView.getViewNumber());
        kanbanView.setCreatorId(kanbanViewAddParam.getCurrUserId());
        kanbanView.setPriority(map.get("priority") != null ? map.get("priority")+1 : 1);
        kanbanView.setKanbanType(kanbanViewAddParam.getKanbanType());
        kanbanViewService.save(kanbanView);
        return true;
    }

    /**
     * 编辑view
     * @param param
     * @return
     */
    public boolean updateKanbanView(KanbanUpdateViewParam param){
        KanbanView kanbanView = BeanUtil.copyProperties(param,KanbanView.class);
        kanbanView.setFieldDisplayJson(param.getFieldDisplayJson() == null ? null : param.getFieldDisplayJson().toString());
        kanbanView.setFilterObj(param.getFilterObj() == null ? null : param.getFilterObj().toString());
        kanbanView.setKanbanType(param.getViewType());
        return  kanbanViewService.updateById(kanbanView);
    }

    /**
     * view列表
     * @return
     */
    public List<KanbanViewResp> getAllViewsByKanban(String kanbanId){
        List<KanbanViewResp> respList = new ArrayList<>();
        List<KanbanView> list = kanbanViewService.getAllKanbanViews(kanbanId);
        list.stream().forEach(bean ->{
            KanbanViewResp resp = new KanbanViewResp();
            BeanUtil.copyProperties(bean,resp);
            /** 创建 ObjectMapper 对象*/
            ObjectMapper objectMapper = new ObjectMapper();
            /**解析 JSON 字符串为 JsonNode*/
            JsonNode jsonNode = null;
            try {
                jsonNode = objectMapper.readTree(bean.getFieldDisplayJson());
            } catch (JsonProcessingException e) {
                ExceptionUtil.throwBizException(ResultCodeEnum.KANBAN_TASK_NOT_NULL);
            }

            /**统计可见数量*/
            Long visibleNum = 0L;
            /**统计隐藏数量*/
            Long hideNum = 0L;
            // 遍历 JSON 数组中的元素
            for (JsonNode element : jsonNode) {
                for (JsonNode value : element) {
                    if (value.isBoolean() && value.booleanValue()) {
                        visibleNum++;
                    }else {
                        hideNum++;
                    }
                }
            }
            resp.setVisibleNum(visibleNum);
            resp.setHideNum(hideNum);
            resp.setFieldDisplayJson_json(new JSONArray(bean.getFieldDisplayJson()));
            resp.setFilterObj_json(JSON.parseObject(bean.getFilterObj()));
            respList.add(resp);
        });
        return respList;
    }

    /**
     * 移动view
     * @param kanbanViewMoveParam
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean moveView(KanbanViewMoveParam kanbanViewMoveParam){
        Integer priority;
        if(kanbanViewMoveParam.getReplaceId() == null){
            /**表示移动到最后一个*/
            priority = kanbanViewService.maxPriority(kanbanViewMoveParam.getKanbanId())+1;
        }else {
            KanbanView replaceView = kanbanViewService.getById(kanbanViewMoveParam.getReplaceId());
            /**移动view*/
            kanbanViewService.viewPriorityAfter(replaceView.getPriority(),kanbanViewMoveParam.getKanbanId());
            priority = replaceView.getPriority();
        }
        /**更新view 优先级*/
        kanbanViewService.updateViewPriority(kanbanViewMoveParam.getId(),priority,kanbanViewMoveParam.getKanbanId());
        return true;
    }
}
